﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ClassLibraryMessageDataType;
using System.Threading;
using System.Collections;
using ClassLibraryMessageDispacher;
using LogRecord;
using System.Windows.Forms;
using System.Drawing;
namespace GUI
{
    public sealed   class ClassMiddleClientBusiness
    {
        private  ClassWorkStepsCollections[] worksteps = null;
        private Thread athread;
        public  string middleClientip = string.Empty;
        private Queue<ClassWorkStepsCollections> workstepsquenue = new Queue<ClassWorkStepsCollections>();

        private OneClientAll64BoardData_Manager oneclientall64boardatamanager = new OneClientAll64BoardData_Manager();

        private TextBox clientTextboxStatus = null;

        public ClientStatusInfo thisClientInfoBoard = new ClientStatusInfo { nextStatus = MiddleclientBusinessStatus.init, nowStatus = MiddleclientBusinessStatus.init };
        public void SetClientTextBoxStatusHandle( ref TextBox t)
        {
            clientTextboxStatus = t;
        }
       public void setMiddleclientBusinessStatus(MiddleclientBusinessStatus its)
        {
            thisClientInfoBoard.nextStatus = its;
        }

        private void  SetTextBoxColorAndText(Color c,string txt)
        {
            clientTextboxStatus.BeginInvoke((EventHandler)(delegate
            {
                clientTextboxStatus.BackColor = c;
                clientTextboxStatus.Text = txt;
            }));
              
        }
        public void outMiddleclientBusinessStatus( out MiddleclientBusinessStatus its)
        {
           its = thisClientInfoBoard.nowStatus;
        }
        public ClassMiddleClientBusiness()
        {
            athread = new Thread(fsm_back_thread);
            athread.Priority = ThreadPriority.Normal;
            athread.IsBackground = true;
            athread.Start();
        }

       public   void PushWsIntoDquenueArry(ref ClassWorkStepsCollections []arry)
        {    
            LogRecord.Log.mInstance.WriteCommonLog(" push work steps arry in  middledev bussiness  -> push work steps number is :" + arry.Length.ToString());
            foreach (var ar in arry)
            {
                workstepsquenue.Enqueue(ar);          
            }
        }
        public void PushWsIntoDquenue(ref ClassWorkStepsCollections cwsc)
        {
                LogRecord.Log.mInstance.WriteCommonLog(" push work one steps  in  middledev bussiness  ->work steps type is : " + cwsc.workStepsType.ToString("x2"));
       
                workstepsquenue.Enqueue(cwsc);
            
        }

        private  void CheckNeed2SendDbRealData()
        {
            if(oneclientall64boardatamanager.RefreshCount >= 640)
            {
              oneclientall64boardatamanager.RefreshCount = 0;
              Task.Run(() =>
              {
                  //电池的数据


              });
                              
            }else
            {
                Thread.Sleep(10);
            }
        }
        private bool CheckAll640BatPonitWorkDown()
        {
            bool isDown = true;
            for (int aboard = 0; aboard < oneclientall64boardatamanager.all64boarddata.all64boardBatpointdataAarry.Length; aboard++)//64
            {

                for (int batPoint = 0; batPoint < oneclientall64boardatamanager.all64boarddata.all64boardBatpointdataAarry[aboard].oneboardBatpointdataArry.Length; batPoint++)//10
                {
                    Thread.Sleep(1);
                    if (oneclientall64boardatamanager.all64boarddata.all64boardBatpointdataAarry[aboard].oneboardBatpointdataArry[batPoint].status >= 0x04)
                    {

                    }
                    else
                    {
                        isDown = false;
                        return isDown;
                    }
                }
            }
            return isDown;
   
        }

        private  void fsm_back_thread(object a)
        {
            while(true)
            {
                Thread.Sleep(100);

                switch(thisClientInfoBoard.nowStatus)
                {
                    case MiddleclientBusinessStatus.err:
                        {
                            SetTextBoxColorAndText(Color.Red, "错误");

                        }
                        break;
                    case MiddleclientBusinessStatus.outofline:
                        {
                            SetTextBoxColorAndText(Color.Gray, "离线");
                        }
                        break;
                    case MiddleclientBusinessStatus.init:
                        {
                            SetTextBoxColorAndText(Color.White, "初始");
                        }
                        break;

                    case MiddleclientBusinessStatus.free:
                        {
                            SetTextBoxColorAndText(Color.LightGreen, "空闲");
                            if (workstepsquenue.Count > 0)
                            {                                                   
                                    thisClientInfoBoard.nextStatus = MiddleclientBusinessStatus.busy_downloadWorkSteps;
                                    Thread.Sleep(200);
                                    break;                               
                            }                      
                            thisClientInfoBoard.nextStatus = MiddleclientBusinessStatus.free;
                            Thread.Sleep(100);
                        }
                        break;
                    case MiddleclientBusinessStatus.busy_downloadWorkSteps:
                        {
                            SetTextBoxColorAndText(Color.LightBlue, "下单");
                            if (middleClientip != string.Empty)
                            {
                                //下发工步
                                if (workstepsquenue.Count > 0)
                                {

                                   ClassWorkStepsCollections workstepA = workstepsquenue.First();

                                    byte[] workstepsarry = StructByteConver.StructToBytes(workstepA);
            
                                    if (ClassUI2MiddleCMDCollections.DownLoadWorkSteps(this.middleClientip, ref workstepsarry))
                                    {

                                        
                                        thisClientInfoBoard.nowDoWorkStepsinfo = workstepA;
                                        Log.mInstance.WriteCommonLog(this.middleClientip + " send down work steps OK ->" + "  work steps :" + thisClientInfoBoard.nowDoWorkStepsinfo.workStepsType.ToString("x2"));                              
                                        workstepsquenue.Dequeue();
                                        MiddleDevClientWorkStatusChange();
                                        thisClientInfoBoard.nextStatus = MiddleclientBusinessStatus.busy_doWorkSteps;
                               
                                        Log.mInstance.WriteCommonLog(this.middleClientip + " into busy_doWorkSteps status");
                                    }
                                    else
                                    {
                                        Log.mInstance.WriteLog(ClassLibraryOverLog._LogStrClassify.Error, this.middleClientip+ " send down work steps Failed");                                   
                                        Thread.Sleep(500);
                                    }

                                    Thread.Sleep(500);

                                }
                                else
                                {

                                }

                                }else
                                {

                                }
                                
                        }
                        break;

                    case MiddleclientBusinessStatus.busy_doWorkSteps:
                        {
                            SetTextBoxColorAndText(Color.DarkBlue, "忙碌");
                            switch (thisClientInfoBoard.nowDoWorkStepsinfo.workStepsType )
                            {
                                
                                case 0x00: //搁置
                                    {
                                        Thread.Sleep(900);
                                        Log.mInstance.WriteCommonLog(this.middleClientip + ": this Steps :  hold on");
                                        if (thisClientInfoBoard.nowDoWorkStepsinfo.limitTime > 0)
                                        {
                                            thisClientInfoBoard.nowDoWorkStepsinfo.limitTime -= 1;
                                            Log.mInstance.WriteCommonLog(this.middleClientip + ": th is step hol on limit time:" + thisClientInfoBoard.nowDoWorkStepsinfo.limitTime.ToString());
                                        }
                                        else
                                        {
                                            Log.mInstance.WriteCommonLog(this.middleClientip + ": into busy_downloadWorkSteps");
                                            thisClientInfoBoard.nextStatus = MiddleclientBusinessStatus.busy_downloadWorkSteps;
                                        }

                                    }
                                    break;
                                case 0x01: //恒流充电
                                    {                                   
                                        if(CheckAll640BatPonitWorkDown())
                                        {
                                            Log.mInstance.WriteCommonLog(this.middleClientip + ": all bat point is down over");
                                            thisClientInfoBoard.nextStatus = MiddleclientBusinessStatus.busy_downloadWorkSteps;
                                        }
                                        else
                                        {
                                            Thread.Sleep(10);
                                        }

                                    }
                                    break;
                                case 0x02://恒流恒压
                                    {
                                        if (CheckAll640BatPonitWorkDown())
                                        {
                                            Log.mInstance.WriteCommonLog(this.middleClientip + ": all bat point is down over");
                                            thisClientInfoBoard.nextStatus = MiddleclientBusinessStatus.busy_downloadWorkSteps;
                                        }
                                        else
                                        {
                                            Thread.Sleep(10);
                                        }

                                    }
                                    break;
                                case 0x03://恒流放电
                                    {
                                        if (CheckAll640BatPonitWorkDown())
                                        {
                                            Log.mInstance.WriteCommonLog(this.middleClientip + ": all bat point is down over");
                                            thisClientInfoBoard.nextStatus = MiddleclientBusinessStatus.busy_downloadWorkSteps;
                                        }
                                        else
                                        {
                                            Thread.Sleep(10);
                                        }

                                    }
                                    break;
                                case 0x0a://wait
                                    {
                                        Log.mInstance.WriteCommonLog(this.middleClientip + ": all bat point is waiting for classifiction");
                                        thisClientInfoBoard.nextStatus = MiddleclientBusinessStatus.waiting;
                                        Thread.Sleep(100);
                                    }
                                    break;

                                case 0x0b: //CLASSIFIED
                                    {
                                       
                                    }
                                    break;

                                case 0x10:// GAME START
                                    {

                                        ClassUI2DBCMDCollections.NotifyStartWorkSteps(this.middleClientip, DateTime.Now.ToString("yyyyMMddHHmmss"));
                                        Log.mInstance.WriteCommonLog(this.middleClientip + ": all bat 2 chargr start");
                                        thisClientInfoBoard.nextStatus = MiddleclientBusinessStatus.busy_downloadWorkSteps;
                                        Thread.Sleep(200);

                                    }
                                    break;

                                case 0x11:// GAME OVER CMD
                                    {


                                    }break;

                                   
                                default:break;
                            }

                        }
                        break;
                    case MiddleclientBusinessStatus.waiting:
                        {
                            SetTextBoxColorAndText(Color.Yellow, "等待");
                            Thread.Sleep(100);
                            Log.mInstance.WriteCommonLog(this.middleClientip + ": all bat for waiting to be classified 等待分类（分容）");
                        }
                        break;

                    default:break;



                }

                if (thisClientInfoBoard.nextStatus!= thisClientInfoBoard.nowStatus)
                {
                    thisClientInfoBoard.nowStatus = thisClientInfoBoard.nextStatus;                 
                }
                else
                {

                }


            }
        }

        protected void MiddleDevClientWorkStatusChange()
        {
            Log.mInstance.WriteCommonLog("NotifyWorkStepsChangeEvent");
            ClassUI2DBCMDCollections.NotifyWorkStepsChangeEvent_changeUnityInfosWatchBoard(this.middleClientip, DateTime.Now.ToString("yyyyMMddHHmmss"), (byte)thisClientInfoBoard.nextStatus, thisClientInfoBoard.nowDoWorkStepsinfo.workStepsType);
            ClassUI2DBCMDCollections.NotifyWorkStepsChangeEvent_updateall640data(this.middleClientip, DateTime.Now.ToString("yyyyMMddHHmmss"), (byte)thisClientInfoBoard.nextStatus, thisClientInfoBoard.nowDoWorkStepsinfo.workStepsType, ref oneclientall64boardatamanager.all64boarddata);        
        }

        public void DealPyshInMessages( ref MessagePackage inMes)
        {
            if(inMes.soure == MessagePackagePath.NetMiddleDeviceCom)
            { 
                    byte[] getarry = inMes.bytesArry.Array;
                    byte mainCMD = getarry[4];
                    byte subCMD = getarry[5];
                try
                {

                    switch (mainCMD)
                    {

                        case 0x02:
                            {

                                switch (subCMD)
                                {
                                    case 0x01:
                                        {
                                            OneProcolRealTimeData_ALL oneRealdataall_16 = (OneProcolRealTimeData_ALL)StructByteConver.BytesToStuct(getarry.Skip(8).Take(1056).ToArray(), typeof(OneProcolRealTimeData_ALL));
                                            for (int a = 0; a < oneRealdataall_16.oneProcolrealtimedata.Length; a++)
                                            {
                                                byte boardcode = oneRealdataall_16.oneProcolrealtimedata[a].boardcode;

                                                oneclientall64boardatamanager.all64boarddata.all64boardBatpointdataAarry[boardcode].boardcode = boardcode;
                                                for (int b = 0; b < oneRealdataall_16.oneProcolrealtimedata[a].pointrealtimedataArrys.Length; b++)
                                                {
                                                    byte batPositionCode = oneRealdataall_16.oneProcolrealtimedata[a].pointrealtimedataArrys[b].positioncode;
                                                    oneclientall64boardatamanager.all64boarddata.all64boardBatpointdataAarry[boardcode].oneboardBatpointdataArry[batPositionCode - 1].boardcode = boardcode;
                                                    oneclientall64boardatamanager.all64boarddata.all64boardBatpointdataAarry[boardcode].oneboardBatpointdataArry[batPositionCode - 1].positioncode = oneRealdataall_16.oneProcolrealtimedata[a].pointrealtimedataArrys[b].positioncode;
                                                    oneclientall64boardatamanager.all64boarddata.all64boardBatpointdataAarry[boardcode].oneboardBatpointdataArry[batPositionCode - 1].status = oneRealdataall_16.oneProcolrealtimedata[a].pointrealtimedataArrys[b].status;
                                                    oneclientall64boardatamanager.all64boarddata.all64boardBatpointdataAarry[boardcode].oneboardBatpointdataArry[batPositionCode - 1].finishedreason = oneRealdataall_16.oneProcolrealtimedata[a].pointrealtimedataArrys[b].finishedreason;
                                                    oneclientall64boardatamanager.all64boarddata.all64boardBatpointdataAarry[boardcode].oneboardBatpointdataArry[batPositionCode - 1].volate = ClassBigLittleConver.The16bitFrontnextChange(oneRealdataall_16.oneProcolrealtimedata[a].pointrealtimedataArrys[b].volate);
                                                    oneclientall64boardatamanager.all64boarddata.all64boardBatpointdataAarry[boardcode].oneboardBatpointdataArry[batPositionCode - 1].current = ClassBigLittleConver.The16bitFrontnextChange(oneRealdataall_16.oneProcolrealtimedata[a].pointrealtimedataArrys[b].current);
                                                    oneclientall64boardatamanager.all64boarddata.all64boardBatpointdataAarry[boardcode].oneboardBatpointdataArry[batPositionCode - 1].capacity = ClassBigLittleConver.The16bitFrontnextChange(oneRealdataall_16.oneProcolrealtimedata[a].pointrealtimedataArrys[b].capacity);
                                                    oneclientall64boardatamanager.all64boarddata.all64boardBatpointdataAarry[boardcode].oneboardBatpointdataArry[batPositionCode - 1].timepriod = ClassBigLittleConver.The16bitFrontnextChange(oneRealdataall_16.oneProcolrealtimedata[a].pointrealtimedataArrys[b].timepriod);
                                                    oneclientall64boardatamanager.all64boarddata.all64boardBatpointdataAarry[boardcode].oneboardBatpointdataArry[batPositionCode - 1].errorcode = ClassBigLittleConver.The16bitFrontnextChange(oneRealdataall_16.oneProcolrealtimedata[a].pointrealtimedataArrys[b].errorcode);
                                                    oneclientall64boardatamanager.RefreshCount++;
                                                }
                                            }
                                        }
                                        break;
                                    case 0x02:
                                        {

                                        }
                                        break;

                                    default: break;
                                }


                            }
                            break;
                        default: break;

                    }
                }
                catch (Exception e)
                {
                    Log.mInstance.WriteLog(ClassLibraryOverLog._LogStrClassify.Error, "DealPyshInMessages excp" + e.Message);
                    string outda = string.Empty;
                    byte[] arry1 = getarry.Skip(8).Take(1056).ToArray();
                    for (int a2 = 0; a2 < arry1.Length; a2++)
                    {
                        outda = outda + " " + arry1[a2].ToString("x2");
                    }
                    Log.mInstance.WriteLog(ClassLibraryOverLog._LogStrClassify.Error, "ERR DATA:" + outda);
                }



            }


        }


        public void OutOneClientAll64BoardDataObj(out OneClientAll64BoardData outDB)
        {
            outDB = oneclientall64boardatamanager.all64boarddata;
        }
    }

        public  struct ClientStatusInfo
        {
            public MiddleclientBusinessStatus nowStatus;
            public MiddleclientBusinessStatus nextStatus;
            public ClassWorkStepsCollections nowDoWorkStepsinfo;
            public bool nowDoWorkStepIsDowned;

        } 

        


    public enum MiddleclientBusinessStatus
    {
        /// <summary>
        /// 错误
        /// </summary>
        err = 0,
        /// <summary>
        /// 
        /// </summary>
        init,
        /// <summary>
        /// 离线
        /// </summary>
        outofline,
        /// <summary>
        /// 空闲
        /// </summary>
        free,
        /// <summary>
        /// 忙碌 下发工步
        /// </summary>
        busy_downloadWorkSteps,
        /// <summary>
        /// 执行
        /// </summary>
        busy_doWorkSteps,
        /// <summary>
        /// 等待 分容
        /// </summary>
        waiting,

    }
}
